package edu.chalmers.sdx;

import java.util.ArrayList;
import java.util.HashMap;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import edu.chalmers.targine.ARManager;
import edu.chalmers.targine.Arbject;
import edu.chalmers.targine.Mesh;
import edu.dhbw.andar.util.Model;

public class SkidroidArbject extends Arbject {
	private HashMap<String, Skier> skiers = new HashMap<String, Skier>();
	private Skier localSkier = null;
	private boolean removeLevelParts = false;
	private boolean removeLocalSkier = false;
//	private ArrayList<Skier> newSkiers = new ArrayList<Skier>();
	private ArrayList<String> removeSkierIDs = new ArrayList<String>();
//	private int localSkierID = (int)(Math.random() * 1000000);
	private String localDeviceID;
	
//	private ArrayList<LevelPart> newLevelParts = new ArrayList<LevelPart>();
	
	private ArrayList<LevelPart> levelParts = new ArrayList<LevelPart>();
	
	private ArrayList<Mesh> savedMeshes = new ArrayList<Mesh>();
	
	public int levelIndex = 0;
	public float nextX = 0;
	public float nextY = 0;
	public int nextDirection = 0;
	
	private GameGrid grid;

	public SkidroidArbject(String name, String patternID, String nfcID, String deviceID, Context context) {
		super(name, patternID, nfcID, context);
		localDeviceID = deviceID;
		grid = new GameGrid(40.0f);
		newMeshes.add(grid);
	}
	
	public void addSkier(Model model, String modelName, String deviceID, float posX, float posY, float angle){
		//TODO: remove the old local skier
		model.finalize();
		model = new Model(model, modelName);
		synchronized(newMeshes){
			removeLocalSkier = false;
			Skier newSkier = new Skier(model, levelParts, deviceID);
			if(deviceID.equals(localDeviceID)){
				localSkier = newSkier;
			}
			skiers.put(deviceID, newSkier);
			newMeshes.add(newSkier);
		}
		markForReinitialization();
	}
	
	public void updateSkier(String deviceID, float posX, float posY, float angle){
		if(skiers.containsKey(deviceID)){
			Skier skier = skiers.get(deviceID);
			skier.setPosition(posX, posY, skier.getZPos());
			skier.setDirection(angle);
		}
	}
	
	public boolean hasSkier(String deviceID){
		for(Skier skier : skiers.values()){
			if(skier.hasID(deviceID)){
				return true;
			}
		}
		return false;
	}
	
	public void changeSkierAngle(float da){
		if(localSkier != null){
			localSkier.changeDirection(da);
		}
	}
	
//	public void setValue(String var, String value){
//		if(var.equals("LEVEL")){
////			setLevel(value.split(","));
//			this.value = value;
//			updateLevel();
//		}
//		else if(var.equals("PLAYER")){
//			String[] parsedPlayer = value.split("&");
//			if(parsedPlayer[1].equals("none")){
//				//remove skier
//				removeSkier(Integer.parseInt(parsedPlayer[0]));
//			} else{
//				//update skier
//				updateSkier(Integer.parseInt(parsedPlayer[0]), 
//							Float.parseFloat(parsedPlayer[1]), 
//							Float.parseFloat(parsedPlayer[2]));
//			}
//		}
//	}
	
	public void removeSkier(String deviceID){
		if(skiers.containsKey(deviceID)){
			//remove non-local skier
			synchronized (removeSkierIDs){
				removeSkierIDs.add(deviceID);
			}
			markForReinitialization();
		}
	}
	
//	public void updateSkier(String id, float xpos, float ypos){
//		if(skiers.containsKey(""+id)){
//			//update non-local skier
//			skiers.get(id).setPosition(xpos, ypos, 0f);
//		} else if(localDeviceID.equals(id)){
//			//what do?
//		} else{
//			Model newSkierModel = ARManager.models.get("skier");
//			newSkierModel.finalize();
//			newSkierModel = new Model(newSkierModel, "skier");
//			Skier newSkier = new Skier(newSkierModel, levelParts, id);
//			newSkier.setPosition(xpos, ypos, 0f);
//			newSkiers.add(newSkier);
//			markForReinitialization();
//		}
//	}
	
//	public void addLevelPart(String partType){
//		if(value.equals("none")){
//			value = "";
//		}
//		
//		if(ARManager.models.containsKey(partType)){
//			value += "," + partType;
//		} else{
//			value += ",none";
//		}
//		
//		if(value.charAt(0) == ','){
//			value = value.substring(1);
//		}
//		updateLevel();
//	}
	
//	public void setLevel(String[] newValue){
//		String tmpValue = "";
//		for(int i = 0; i < newValue.length; i++){
//			if(ARManager.models.containsKey(newValue[i])){
//				tmpValue += "," + newValue[i];
//			} else{
//				tmpValue += ",none";
//			}
//		}
//		if(tmpValue.charAt(0) == ','){
//			tmpValue = tmpValue.substring(1);
//		}
//		value = tmpValue;
//		updateLevel();
//	}
	
	public void addLevelPart(String partType, float posX, float posY){
		Model newModel = ARManager.models.get(partType);
		newModel.finalize();
		newModel = new Model(newModel, partType);
		LevelPart newLevelPart = new LevelPart(newModel, partType, posX, posY);
		newMeshes.add(newLevelPart);
		nextX += 80;
		levelIndex++;
		markForReinitialization();
	}
	
	public void setLevelPart(int index, String partType, float posX, float posy){
		//TODO: search for levelpart with index and set this to a new part
	}
	
	public void clearLevel(){
		nextX = 0;
		levelIndex = 0;
		resetModels = true;
		markForReinitialization();
	}
	
//	public void updateLevel(){
//		String[] parsedValue = value.split(",");
//		if(parsedValue[0].equals("none")){
//			//welcome to die§
//			clearLevel();
//		} else{
//			for(int i = 0; i < parsedValue.length; i++){
//				if(ARManager.models.containsKey(parsedValue[i])){
//					if(i >= levelParts.size()){
//						//add levelPart
//						hasModel = true;
//						Model newModel = ARManager.models.get(parsedValue[i]);
//						newModel.finalize();
//						newModel = new Model(newModel, parsedValue[i]);
//						
//						if(levelParts.size() == 0){
//							newModel.xpos = i * 80f;
//						}
//						else{
//							updateCoordinatesAndDirection(levelParts.get(levelParts.size() - 1));
//							newModel.xpos = nextX;
//							newModel.ypos = nextY;
//						}
//						
//						synchronized(newLevelParts){
//							if(newLevelParts.size() == 0){
//								newLevelParts.addAll(levelParts);
//							}
//							newLevelParts.add(new LevelPart(newModel, parsedValue[i], 0, 0));
//						}
//					} else{
//						//change level part at this index
//						hasModel = true;
//						Model newModel = ARManager.models.get(parsedValue[i]);
//						newModel.finalize();
//						newModel = new Model(newModel, parsedValue[i]);
//						
//						if(i == 0){
//							newModel.xpos = i * 80f;
//						}
//						else{
//							updateCoordinatesAndDirection(levelParts.get(i - 1));
//							newModel.xpos = nextX;
//							newModel.ypos = nextY;
//						}
//
//						synchronized(newLevelParts){
//							if(newLevelParts.size() == 0){
//								newLevelParts.addAll(levelParts);
//							}
//							newLevelParts.set(i, new LevelPart(newModel, parsedValue[i], 0, 0));
//						}
//					}
//				}
//				//no diff, do nothing
//			}
//		}
//		dirty = false;
//		markForReinitialization();
//	}
	
//	private void updateCoordinatesAndDirection(LevelPart previousLevelPart){
//		switch(previousLevelPart.getDirection()){
//			case LevelPart.DIRECTION_FORWARD:
//				nextX = previousLevelPart.getXPos() + 80f;
//				nextY = previousLevelPart.getYPos();
//				break;
//			case LevelPart.DIRECTION_LEFT:
//				nextX = previousLevelPart.getXPos();
//				nextY = previousLevelPart.getYPos() + 80f;
//				nextDirection = (nextDirection + 1) % 2;
//				break;
//			case LevelPart.DIRECTION_RIGHT:
//				nextX = previousLevelPart.getXPos();
//				nextY = previousLevelPart.getYPos() - 80f;
//				if(nextDirection-- < 0){
//					nextDirection = 2;
//				}
//				break;
//		}
//	}
	
	public void removeLocalPlayer(){
		localSkier = null;
		removeLocalSkier = false;
	}
	
	public boolean isLocalPlayerMarkedForRemoval(){
		return removeLocalSkier;
	}
	
	public boolean hasLocalPlayer(){
		return localSkier != null;
	}
	
	public String getLocalSkierValue(){
		return localDeviceID + "," + localSkier.getXPos() + "," + localSkier.getYPos() + "," + localSkier.getAngle();
	}
	
	public String getRemovePlayerValue(){
		return localSkier.getID() + "&" + "none";
	}
	
	public int getLevelSize(){
		return levelParts.size();
	}
	
	@Override
	public void init(GL10 gl){
		if(resetModels){
			removeLevelParts = true;
			for(Mesh mesh : meshes){
				if(!mesh.hasType(SkidroidXtreme.SLOPE)){
					savedMeshes.add(mesh);
				}
			}
		}
		super.init(gl);
	}
	
	@Override
	public void draw(GL10 gl){
		if(removeLevelParts){
			meshes.addAll(savedMeshes);
			savedMeshes = new ArrayList<Mesh>();
			removeLevelParts = false;
		}
//		if(levelParts.size() != value.split(",").length){
//			dirty = true;
//		}
		super.draw(gl);
	}
}
